//
//	HOME AUTOMATION GATEWAY PROJECT
//
//  (c) 2008 mocom software GmbH & Co KG
//	for European Microsoft Innovation Center
//
//  $Author: volker $
//  $Date: 2009-03-13 16:07:41 +0100 (Fr, 13. Mrz 2009) $
//  $Revision: 286 $
//
//  Microsoft dotNetMF Project
//  Copyright ©2001,2002,2003,2004 Microsoft Corporation
//  One Microsoft Way, Redmond, Washington 98052-6399 U.S.A.
//  All rights reserved.
//  MICROSOFT CONFIDENTIAL
//
//-----------------------------------------------------------------------------
#ifndef __AX88796B_H__
#define __AX88796B_H__

#include <tinyhal.h>

#define AX88796B_WATCHDOG_PERIOD (2*HZ)

/*---------------------------------------------------------------
	MAC register
---------------------------------------------------------------*/
#define NIC_COMMAND			0x0		// (CR)
#define NIC_PAGE_START		0x1		// (PSTART)		MSB, write-only
#define NIC_PHYS_ADDR		0x1		// (PAR0)		page 1
#define NIC_PAGE_STOP		0x2		// (PSTOP)		MSB, write-only
#define NIC_BOUNDARY		0x3		// (BNRY)		MSB
#define NIC_XMIT_START		0x4		// (TPSR)		MSB, write-only
#define NIC_XMIT_STATUS		0x4		// (TSR)		read-only
#define NIC_XMIT_COUNT_LSB	0x5		// (TBCR0)		write-only
#define NIC_XMIT_COUNT_MSB	0x6		// (TBCR1)		write-only
#define NIC_CURRENT			0x6		// (CURR)		page 0
#define NIC_INTR_STATUS		0x7		// (ISR)
#define NIC_MC_ADDR			0x8		// (MAR0)		page 1
#define NIC_CRDA_LSB		0x8		// (CRDA0)
#define NIC_RMT_ADDR_LSB	0x8		// (RSAR0)
#define NIC_CRDA_MSB		0x9		// (CRDA1)
#define NIC_RMT_ADDR_MSB	0x9		// (RSAR1)
#define NIC_RMT_COUNT_LSB	0xa		// (RBCR0)		write-only
#define NIC_RMT_COUNT_MSB	0xb		// (RBCR1)		write-only
#define NIC_RCV_CONFIG		0xc		// (RCR)		write-only
#define NIC_RCV_STATUS		0xc		// (RSR)		read-only
#define NIC_XMIT_CONFIG		0xd		// (TCR)		write-only
#define NIC_MISC_CONFIG		0xd		// (MISC)		write-only
#define NIC_FAE_ERR_CNTR	0xd		// (CNTR0)		read-only
#define NIC_DATA_CONFIG		0xe		// (DCR)		write-only
#define NIC_CRC_ERR_CNTR	0xe		// (CNTR1)		read-only
#define NIC_INTR_MASK		0xf		// (IMR)		write-only
#define NIC_MISSED_CNTR		0xf		// (CNTR2)		read-only
#define NIC_RACK_NIC		0x10	// 				Byte to read or write
#define NIC_IFG				0x12	// (IFGS) 		Inter frame gap (16-Bit)
#define NIC_MII_ACCESS		0x14	// 				MII
#define NIC_BUFFER_TYPE_CFG	0x15	// (BTCR)
#define NIC_IFG_3			0x16	// (IFG)
#define NIC_DSR				0x17	// (DSR)		read-only
#define NIC_BPJL			0x17	// (BPJL)		write-only
#define NIC_MAX_FARME_SIZE	0x18	// (MFS)
#define NIC_FLOW_CONTROL	0x1a	// (FCR)
#define NIC_MAC_CONFIG		0x1b	// (MCR)
#define NIC_CUR_TX_END_PAGE	0x1c	// (CTEPR)		write-only
#define NIC_VLAN_ID			0x1c	// (VLANID)		read-only
#define NIC_BIG_ENDIAN		0x1e	// (BER)
#define NIC_RESET			0x1f	// (RESET)

// Constants for the NIC_COMMAND register.
#define CR_STOP				(UINT8)0x01	// reset the card
#define CR_START			(UINT8)0x02	// start the card
#define CR_XMIT				(UINT8)0x04	// begin transmission
#define CR_STOP_DMA			(UINT8)0x20	// stop remote DMA
#define CR_PAGE0			(UINT8)0x00 // select page 0
#define CR_PAGE1			(UINT8)0x40	// select page 1
#define CR_PAGE2			(UINT8)0x80 // select page 2
#define CR_PAGE3			(UINT8)0xC0	// select page 3
#define CR_DMA_WRITE		(UINT8)0x10	// Write
#define CR_DMA_READ			(UINT8)0x08	// Read

// Constants for the NIC_XMIT_STATUS register.
#define TSR_XMIT_OK			(UINT8)0x01	// transmit with no errors
#define TSR_COLLISION		(UINT8)0x04	// collided at least once
#define TSR_ABORTED			(UINT8)0x08	// too many collisions

// Constants for the NIC_INTR_STATUS register.
#define ISR_RCV				(UINT8)0x01	// packet received with no errors
#define ISR_XMIT			(UINT8)0x02	// packet transmitted with no errors
#define ISR_RCV_ERR			(UINT8)0x04	// error on packet reception
#define ISR_XMIT_ERR		(UINT8)0x08	// error on packet transmission
#define ISR_OVERFLOW		(UINT8)0x10	// receive buffer overflow
#define ISR_COUNTER			(UINT8)0x20	// MSB set on tally counter
#define ISR_DMA_DONE		(UINT8)0x40	// RDC
#define ISR_RESET			(UINT8)0x80	// (not an interrupt) card is reset

// Constants for the NIC_RCV_CONFIG register.
#define RCR_BROADCAST		(UINT8)0x04	// receive broadcast packets
#define RCR_MULTICAST		(UINT8)0x08	// receive multicast packets
#define RCR_ALL_PHYS		(UINT8)0x10	// receive ALL directed packets
#define RCR_MONITOR			(UINT8)0x20	// don't collect packets
#define RCR_INT_ACT			(UINT8)0x40

// Constants for the NIC_RCV_STATUS register.
#define RSR_PACKET_OK		(UINT8)0x01	// packet received with no errors
#define RSR_CRC_ERROR		(UINT8)0x02	// packet received with CRC error
#define RSR_MULTICAST		(UINT8)0x20	// packet received was multicast
#define RSR_DISABLED		(UINT8)0x40	// received is disabled

// Constants for the NIC_XMIT_CONFIG register.
#define TCR_LOOPBACK		(UINT8)0x02	// loopback (set when NIC is stopped)

// Constants for the NIC_DATA_CONFIG register.
#define DCR_BYTE_WIDE		(UINT8)0x00	// byte-wide DMA transfers
#define DCR_WORD_WIDE		(UINT8)0x01	// word-wide DMA transfers

// Constants for the NIC_INTR_MASK register.
// Configure which ISR settings actually cause interrupts.
#define IMR_RCV				(UINT8)0x01	// packet received with no errors
#define IMR_XMIT			(UINT8)0x02	// packet transmitted with no errors
#define IMR_RCV_ERR			(UINT8)0x04	// error on packet reception
#define IMR_XMIT_ERR		(UINT8)0x08	// error on packet transmission
#define IMR_OVERFLOW		(UINT8)0x10	// receive buffer overflow
#define IMR_COUNTER			(UINT8)0x20	// MSB set on tally counter

#define INT_MASK			(IMR_RCV | IMR_XMIT | IMR_XMIT_ERR | IMR_OVERFLOW)
#define RCV_CONFIG			(RCR_BROADCAST | RCR_INT_ACT)

// xmit space
#define XMIT_NUM_BUF		12
#define XMIT_START_PAGE		0x40
#define XMIT_END_PAGE		(0x40+XMIT_NUM_BUF)

// receive space
#define RCV_START_PAGE		XMIT_END_PAGE
#define RCV_STOP_PAGE		0x80

// Ethernet
#define MAX_ETHERNET_LEN	UIP_BUFSIZE
#define MIN_ETHERNET_LEN	60
#define ETH_ADDR_LEN		6

// Speed Duplex Mode
#define SPEED_DUPLEX_AUTO	((1<<9|(1<<12))
#define SPEED_DUPLEX_100FD	((1<<13)|(1<<8))
#define SPEED_DUPLEX_100HD	((1<<13))
#define SPEED_DUPLEX_10FD	((1<<8))
#define SPEED_DUPLEX_10HD	(0)

typedef struct AX88796B_softc
{
    PIFACE		iface;
    struct      ether_statistics stats;
    int         ia_irq;
	//UINT8 		ax_current_rx_page;
	UINT8 		ax_current_tx_page;
	int 		ax_tx_buffer_full;
    RTP_UINT8   mac_addr[6];
} AX88796B_SOFTC;

UINT16 MiiReadRegister(UINT16 uRegNum);
void MiiWriteRegister(UINT16 uRegNum,UINT16 uRegData);

static UINT8 inline ax_read_reg8(unsigned offset)
{
	UINT8 volatile *reg = (UINT8 volatile *) (AX88796_BASE_ADDRESS + offset);

	return *reg;
}

static void inline ax_write_reg8(unsigned offset, UINT8 data)
{
	UINT8 volatile *reg = (UINT8 volatile *) (AX88796_BASE_ADDRESS + offset);
	
	*reg = data;
}

#ifdef IF_ACCESS_8BIT
static UINT16 inline ax_read_reg16(unsigned offset)
{
	UINT8 volatile *reg = (UINT8 volatile *) (AX88796_BASE_ADDRESS + offset);
	UINT16 data;
	
	data = (UINT16) reg[0];
	data |= ((UINT16) reg[1]) << 8;

	return data;
}

#else
static UINT16 inline ax_read_reg16(unsigned offset)
{
	UINT16 volatile *reg = (UINT16 volatile *) (AX88796_BASE_ADDRESS + offset);

	return *reg;
}
#endif

static void inline ax_write_reg16(unsigned offset, UINT16 data)
{
	UINT16 volatile *reg = (UINT16 volatile *) (AX88796_BASE_ADDRESS + offset);

	*reg = data;
}

#endif  /* #ifndef __AX88796B_H__   */
